/**
 * Author: Lily Jiang
 * Create Time: 2019/12/31
 * Description:
 */

import React from 'react';
import { ListView, Toast } from 'antd-mobile';
import * as actions from "@/store/actions";

export default (pageSize) => WrapComponent => {
    return class PageHoc extends React.Component {
        static displayName = `PageComponent(${WrapComponent.displayName || WrapComponent.name || 'Component'})`;

        wrapComp;
        //  apiFn方法必须定义
        //  getListViewHeight必须，否则取body高度
        //  customerData方法非必要，用于数据整形统一
        //  pageInit非必要，高阶组件本生挂载完成之后的回调，可以用来触发loadFirstPage

        constructor(props){
            super(props);

            this.state = {
                list: [],
                dataSource: new ListView.DataSource({
                    rowHasChanged: (row1, row2) => row1 !== row2,
                }),
                pullLoading: false,
                upLoading: false,
                hasMore: true,
                pageNo: 1,
                pageSize: pageSize || 10,
                height: 0,
            }
        }

        componentDidMount () {
            this.wrapComp.pageInit && this.wrapComp.pageInit()
        }


        changeLoadingState = (status) => {
            this.props.dispatch(actions.updateAppSetting({
                appLoading: status
            }))
        }

        //  首次加载
        loadFirstPage = () => {
            if (!this.wrapComp.getListViewHeight) {
                console.warn('【未在组件中定义getListViewHeight方法，分页控件高度将使用body的高度】')
            }

            this.changeLoadingState(true)
            this.setState({
                pageNo: 1,
                height: (this.wrapComp.getListViewHeight && this.wrapComp.getListViewHeight()) || document.documentElement.clientHeight
            })

            this.loadData(1);
        }

        //  上拉加载
        onEndReached = () => {
            if (this.state.upLoading || !this.state.hasMore || this.state.pullLoading) {
                return;
            }

            this.setState({
                pageNo: this.state.pageNo + 1,
                upLoading: true
            }, () => {
                this.loadData(this.state.pageNo);
            })

        }

        //  下拉刷新
        onRefresh = () => {
            if (this.state.pullLoading) {
                return
            }

            this.setState({
                pullLoading: true,
                pageNo: 1
            })

            this.loadData(1)
        }

        //  请求处理
        loadData = (pageNo) => {
            if (!this.wrapComp.apiFn) {
                console.error('未在组件中定义apiFn方法')
                return
            }

            this.wrapComp.apiFn(pageNo).then(data => {
                if (!data) {
                    console.warn('then中返回有效的数据')
                    return
                }

                let list = pageNo === 1 ? [] : this.state.list

                let resData = {}
                if (this.wrapComp && this.wrapComp.customerData) {      //  数据预处理
                    resData = this.wrapComp.customerData(data)
                } else {
                    resData = {
                        list: data.items
                    }
                }

                this.changeLoadingState(false)
                this.setState({
                    list: [...list, ...resData.list || []],
                    upLoading: false,
                    pullLoading: false,
                    hasMore: resData.list.length < this.state.pageSize ? false : true
                })
            }, err => {
                if (this.state.pageNo != 1) {
                    this.setState({
                        pageNo: this.state.pageNo - 1
                    })
                }

                this.changeLoadingState(false)
                this.setState({
                    upLoading: false,
                    pullLoading: false,
                });

                err.msg && Toast.info(err.msg)
            })
        }

        render(){
            return (
                <WrapComponent
                    ref={com => this.wrapComp = com}
                    {...this.props}
                    {...this.state}
                    changeLoadingState = {this.changeLoadingState}
                    loadFirstPage = {this.loadFirstPage}
                    onEndReached = {this.onEndReached}
                    onRefresh = {this.onRefresh}
                />

            )
        }
    }
}
